home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d11 / vmoire14.arc / VGAMOIRE.ASM < prev    next >
Assembly Source File  |  1991-04-21  |  84KB  |  2,132 lines

  1. ;------ VGAMoire --------------------------------------------------------------
  2. ;
  3. ;       A text mode screen saver which saves the text display and draws a
  4. ;       pretty, moving graphic design on the screen.
  5. ;
  6. ;   ┌──
  7. ;   │   moi│re (mwär, môr) n. [Fr, watered silk < MOHAIR] a fabric, esp. silk,
  8. ;   │      rayon, or acetate, having a watered, or wavy, pattern.
  9. ;   │                 _            _
  10. ;   │   moi│ré (mwär ra', mô-; môr'a) adj. [Fr, pp. of /moirer/, to
  11. ;   │      water < /moire/: see prec.] having a watered, or wavy, pattern,
  12. ;   │      as certain fabrics, stamps, or metal surfaces --n.  1 a watered
  13. ;   │      pattern pressed into cloth, etc. with engraved rollers  2 MOIRE
  14. ;   └┬─
  15. ;    └───────── From Webster's New World Dictionary, Third College Edition,
  16. ;               Copyright (C) 1988 by Simon & Schuster, Inc.
  17. ;
  18. ;------ CREDITS ---------------------------------------------------------------
  19. ;
  20. ;       Moire pattern generator for the VGA.
  21. ;       Written by Christopher Antos, July 1990.
  22. ;       Copyright (C) 1990 by Christopher Antos.
  23. ;
  24. ;       Inspired by seeing MAGIC for Windows.  Also inspired by a lack of
  25. ;       intelligent, small, pretty screen savers that restored the video and
  26. ;       mouse states correctly.
  27. ;
  28. ;       Linedraw routines are from "Programmer's Guide to PC & PS/2 Video
  29. ;       Systems", from Microsoft Press.
  30. ;
  31. ;       If you have any questions or comments, please contact me at:
  32. ;
  33. ;               Christopher Antos
  34. ;               2115 Windsor Drive
  35. ;               Ann Arbor, MI  48103-5652
  36. ;               (313)663-7912
  37. ;
  38. ;       I'm not too picky about people using this source code.  It is not,
  39. ;       however, public domain.  It is copyrighted.  If you use this source
  40. ;       code at all, then you are using the program, and should feel obligated
  41. ;       to send a donation just as if you were using the program itself.  See
  42. ;       the documentation for more information.
  43. ;
  44. ;------ COMPILING -------------------------------------------------------------
  45. ;
  46. ;       VGAMoire is written for Turbo Assembler 2.0 and uses "SMART" mode for
  47. ;       maximum code optimization.
  48. ;
  49. ;       To compile:
  50. ;
  51. ;               tasm /zi vgamoire
  52. ;               tlink /v /s /l vgamoire
  53. ;               del vgamoire.obj
  54. ;               tdstrip -s -c vgamoire
  55. ;
  56. ;       This creates the excutable file, VGAMOIRE.COM; the debugger symbol
  57. ;       table file, VGAMOIRE.TDS; and the map file, VGAMOIRE.MAP.
  58. ;
  59. ;------ PLANS FOR REVISION ----------------------------------------------------
  60. ;
  61. ;       - Display new settings when N is used.
  62. ;       - Possibly some more code compaction.
  63. ;       - Possibly rearrange routines and only keep large routines (ie,
  64. ;         character RAM save/restore routines) resident if they will be used.
  65. ;       - Possibly implement XMS support, if in demand enough.
  66. ;
  67. ;------ VERSION HISTORY -------------------------------------------------------
  68. ;
  69. ;       v1.0    7/14/90
  70. ;               ■       Original version.
  71. ;               ■       Details:
  72. ;                         - Works with monochrome or color VGA cards only.
  73. ;                           VGAMoire will not work on EGA or MCGA, but it
  74. ;                           should work on just about any VGA card.  It uses
  75. ;                           the VGA 640x480x16 mode 12h, and uses 15 colors.
  76. ;                           It directly accesses the video DAC color registers
  77. ;                           and reprograms them to display different colors.
  78. ;                         - Will not work in graphics modes.  It is highly
  79. ;                           unlikely this will change, though someday, if
  80. ;                           the idea is popular and in demand enough, support
  81. ;                           *may* be added to save the graphics screen to EMS,
  82. ;                           allowing VGAMoire to be able to work even in
  83. ;                           graphics modes (though it still would conflict with
  84. ;                           most games or other "poorly behaved" programs).  I
  85. ;                           just don't see the point in it, especially since
  86. ;                           graphical applications are leaning towards
  87. ;                           Microsoft Windows as a standard.  Real-mode DOS
  88. ;                           TSRs like VGAMoire would not function, anyhow.
  89. ;                         - Does not beep if it times out in graphics mode, but
  90. ;                           beeps any other time it cannot pop up, including
  91. ;                           if the user hits Ctrl-Alt-Shift while in graphics
  92. ;                           mode.
  93. ;                         - Respects serial (and some parallel) communications,
  94. ;                           and restarts its countdown while any data transfer
  95. ;                           is going on.  It will not break carrier when it
  96. ;                           pops up or down (unless the remote host times out).
  97. ;                         - Saves and restores the complete mouse state.
  98. ;                         - Restores the display when mouse movement or a
  99. ;                           keypress is detected.  Note that VGAMoire suspends
  100. ;                           the current process.  It is NOT a background
  101. ;                           process.
  102. ;                         - With EMS memory installed, VGAMoire can save the
  103. ;                           *entire* video state, including the character
  104. ;                           generator RAM.  If this feature is not used, or EMS
  105. ;                           memory is not available, then VGAMoire just saves
  106. ;                           and restores the video mode, page, cursor positions
  107. ;                           (for each of the 8 video pages), and the cursor
  108. ;                           shape.  It will reset the screen to 25 lines.  No
  109. ;                           video data is lost besides the character generator
  110. ;                           RAM and the screen size.
  111. ;                           NOTE:  saving the character generator RAM adds an
  112. ;                           extra 64k to the total EMS memory that VGAMoire
  113. ;                           uses, in order to save all 8 character generator
  114. ;                           RAM banks (at 8k each).
  115. ;                         - VGAMoire should never pop up when it might damage
  116. ;                           the system or cause errors.  It monitors a number
  117. ;                           of I/O interrupts and restarts its countdown if any
  118. ;                           I/O is detected.  If you need an ABSOLUTE guarantee
  119. ;                           that it will not disrupt the system during a vital
  120. ;                           operation, you can turn it off by pressing
  121. ;                           Ctrl-Alt-E (press Ctrl-Alt-B to turn it on again).
  122. ;                           If you press Ctrl-Alt-Shift to pop VGAMoire up, it
  123. ;                           WILL pop up, even if a vital system operation is in
  124. ;                           progress (eg, disk I/O).  Because this can cause
  125. ;                           errors or even crash the system, you should be
  126. ;                           careful about when you pop VGAMoire up manually.
  127. ;                           The only times VGAMoire will not pop up is if the
  128. ;                           display is in a graphics mode or if you are using
  129. ;                           EMS and there is an error while trying to use EMS.
  130. ;                         - Cannot (as yet) detect mouse movement except when
  131. ;                           popped up, so mouse movement will not restart the
  132. ;                           countdown.
  133. ;
  134. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  135. ;
  136. ;       v1.1    8/2/90
  137. ;               ■       Now deallocates its environment block.
  138. ;               ■       Can now select how many character generator RAM blocks
  139. ;                       to save, from 1 to 8.  Allocates an extra one EMS page
  140. ;                       (16k) per every two character generator RAM blocks that
  141. ;                       are saved, so to save 1 or 2 blocks, it takes 16k of
  142. ;                       EMS; for 3 or 4, it takes 32k; etc.
  143. ;               ■       At Karen's request, VGAMoire can now mirror the
  144. ;                       pattern in one of four ways:  no mirror, horizontally,
  145. ;                       vertically, or both horizontally and vertically.
  146. ;               ■       Now detects both mouse movement and mouse button
  147. ;                       activity and will reset its countdown.  A new option
  148. ;                       has also been added to disable this feature, in case
  149. ;                       a mouse is not present or an old mouse driver causes
  150. ;                       problems with this feature.
  151. ;               ■       Bug fix:  might not have worked correctly before if no
  152. ;                       mouse driver were installed (it might have allocated
  153. ;                       an unpredictably-too-large block of memory).
  154. ;               ■       Bug fix:  when only using conventional memory, the
  155. ;                       keyboard would lock up once a key was pressed to
  156. ;                       return from the moire design.  I don't remember quite
  157. ;                       what I did to fix it, although I know I tried a number
  158. ;                       of things.
  159. ;               ■       Now only keeps one color set resident.  When a color
  160. ;                       set is picked, it is copied to the resident copy's
  161. ;                       run-time colorset array (assuming we are changing the
  162. ;                       color set for the resident copy.  It does the same
  163. ;                       thing the first time it is installed, except that of
  164. ;                       course it copies the selected color set into the main
  165. ;                       run-time colorset array).
  166. ;               ■       Frost colors added.
  167. ;
  168. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  169. ;
  170. ;       v1.2    8/7/90
  171. ;               ■       Bug fix:  forgot to use a CS: segment override when
  172. ;                       determining how many font blocks to save/restore, and
  173. ;                       the result was that essentially no fonts were restored.
  174. ;                       VGAMoire now restores fonts correctly.
  175. ;               ■       Also, to avoid some nasty screen flickering during
  176. ;                       some of the special video accesses, we disable the
  177. ;                       video display while operating on video memory, and
  178. ;                       then reenable it after we're done screwing with video
  179. ;                       memory (only when starting up the moire design or
  180. ;                       returning to text mode).
  181. ;               ■       Before, we only redefined 15 colors.  It occured to me
  182. ;                       that VGAMoire should also reprogram the color
  183. ;                       definition for BLACK, to make sure that the black is
  184. ;                       really black.  This is necessary because there are a
  185. ;                       number of programs out that play with the VGA palette,
  186. ;                       and we can't assume that black is really black--we've
  187. ;                       got to MAKE it be black.  The whole purpose of VGAMoire
  188. ;                       is to prevent the monitor from burning out!  If the
  189. ;                       background were always, oh, say WHITE, then VGAMoire
  190. ;                       wouldn't be much use, now would it?  So, anyway, we
  191. ;                       took care of that possibility in this version.
  192. ;
  193. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  194. ;
  195. ;       v1.3    8/14/90
  196. ;               ■       OOPS!  I apologize.  I made a stupid error.
  197. ;                       The [N] option didn't work right.
  198. ;                       Sigh.  This should now be a solid version, w/o
  199. ;                       version changes for a while.  Sigh.
  200. ;
  201. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  202. ;
  203. ;       v1.4    9/4/90
  204. ;               ■       Improved mouse state saving and restoring.  Works
  205. ;                       even with programs making very sophisticated use of
  206. ;                       the mouse driver (for instance, Norton Advanced
  207. ;                       Utilities 5.0).
  208. ;               ■       New method of reading the keyboard and mouse while
  209. ;                       the screen saver is working.  This ensures that
  210. ;                       VGAMoire doesn't receive any "false alerts" and
  211. ;                       refuse to pop up even when it's supposed to.
  212. ;               ■       VGAMoire will now blank out the screen if a graphics
  213. ;                       mode is active.  The moire design will not appear, but
  214. ;                       at least VGAMoire can still function as a screen saver
  215. ;                       even in graphics modes.  Special care was taken so that
  216. ;                       THE PROGRAM CAN STILL RUN IN THE BACKGROUND WHILE THE
  217. ;                       SCREEN IS BLANKED OUT.  The screen will come back if
  218. ;                       VGAMoire detects any activity--mouse, keyboard, serial
  219. ;                       communications, parallel communications (via int 17h),
  220. ;                       video activity (via int 10h), or disk activity.  It
  221. ;                       can be configured to blank the screen in text mode,
  222. ;                       too.
  223. ;
  224. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  225. ;
  226. ;       v1.4b   9/21/90
  227. ;               ■       Source code was reorganized to facilitate future
  228. ;                       support for video cards besides the VGA.  Enough
  229. ;                       people indicated an interest that I decided to
  230. ;                       look into adding support for MDA, CGA, MCGA, EGA,
  231. ;                       VGA, Hercules, and InColor cards.  Note that this is
  232. ;                       NOT a guarantee for support, just a guarantee I'll
  233. ;                       look into it!  Even if I do add support for multiple
  234. ;                       cards, not all of the above cards may be implemented.
  235. ;               ■       Improved video state save/restore routines mean that
  236. ;                       the entire video state is always saved and restored,
  237. ;                       even if EMS memory is not used.  If a non-standard RAM
  238. ;                       font is loaded and active, and the [Fn] option is not
  239. ;                       in effect, then the display will revert to the 8x16
  240. ;                       ROM font.  If one of the ROM fonts was being used
  241. ;                       before VGAMoire took over, then that font will be
  242. ;                       restored.
  243. ;                    ** This also remedies a problem with MS Word (or any
  244. ;                       program that used bright background colors) when the
  245. ;                       [E] option was not used.  Before, VGAMoire was unable
  246. ;                       restore the bright mode, but now it does.
  247. ;               ■       Bug fix:  I forgot to use a CS: segment override when
  248. ;                       dereferencing the "useEMS" flag when popping up
  249. ;                       VGAMoire.  In most situations, this meant VGAMoire
  250. ;                       would nuke any data a program had in the EMS page
  251. ;                       frame (OOPS!).  This has been fixed.
  252. ;
  253. ;------------------------------------------------------------------------------
  254.  
  255.  
  256. LOCALS                                  ;allow local labels in procedures (@@xxx)
  257. SMART                                   ;enable maximum code optimization
  258.  
  259.  
  260. __DeallocateEnvironment         equ     1       ;1=kill env. block, 0=keep env. block so map pgms can ID us
  261.  
  262.  
  263. VERSION         equ     '1.4b'                  ;current version of VGAMoire
  264. DATE            equ     'September 1990'        ;date of this version
  265.  
  266.  
  267. MaxRev          equ     6               ;max times an endpoint direction can reverse before a new random velocity is picked--must be at least 1
  268. MaxLines        equ     50              ;maximum number of lines in the moire pattern
  269.  
  270.  
  271.  
  272.  
  273. cseg    segment para    public  'CODE'
  274.         assume  cs:cseg,ds:cseg,ss:nothing,es:nothing
  275.         org 100h
  276.  
  277.  
  278.  
  279. main    proc    near
  280.         jmp     setup                   ;go to end of program
  281. main    endp
  282.  
  283.  
  284.  
  285. oldmx           dw      0               ;old mouse x-coordinate
  286. oldmy           dw      0               ;old mouse y-coordinate
  287. mouse           db      1               ;flag:  1=check mouse, 0=ignore mouse
  288. delay           db      0               ;delay factor
  289. mirror          db      0               ;mirror setting
  290. length          db      20              ;number of lines in the moire pattern
  291. colorspeed      db      1               ;# of lines to draw before changing color
  292. wait            dw      0               ;number of int 08h's to wait before popping up
  293. buffersize      dw      1000h           ;size of video text save buffer
  294. mousesize       dw      0800h           ;size of mouse state save buffer
  295. fontblocks      db      0               ;number of font RAM blocks to save (0=no font saving, 1-8=that many blocks)
  296. onoff           db      1               ;onoff:  1=on, 0=off
  297. useEMS          db      0               ;useEMS:  1=yes, 0=no
  298. EMShandle       dw      ?               ;our EMS block's handle
  299. counter         dw      0               ;count since a key was pressed etc.
  300. videomode       db      ?               ;previous video mode
  301. storetext       dw      ?               ;where to store text (default for conventional memory)
  302. textbuff        dw      ?               ;store address of text buffer
  303. keybuff         dw      0               ;keyboard buffer
  304. gonow           db      0               ;delay when Ctrl-Alt-Shift is pressed
  305. colorwait       db      0               ;countdown to changing color
  306. curcolor        db      1               ;color of current line
  307. gfxmode         db      0               ;flag:  non-zero indicates we are performing a cop-out version of a screen saver because we're in graphics mode
  308. gfxcopout       db      0               ;flag:  non-zero means always do the cop-out, never draw the moire design
  309. gfxinstalled    db      0               ;flag:  was this copy of VGAMoire installed with the [Bn] option?
  310. timeout         db      1               ;popped up because:  0 if ctrl-alt-shift was hit, 1 if timed out
  311. blackcolor      db      0,0,0           ;video DAC color definition for black
  312. colorset        label   byte            ;run-time array holding color set for moire design--color reg values are loaded in at install time, or these defaults are used
  313.                 db      63,  0,  0      ;color #1       [red]
  314.                 db      63, 30,  0      ;
  315.                 db      63, 45,  0      ;
  316.                 db      63, 63,  0      ;               [yellow]
  317.                 db      42, 63,  0      ;
  318.                 db       0, 63,  0      ;               [green]
  319.                 db       0, 63, 42      ;
  320.                 db       0, 63, 63      ;               [cyan]
  321.                 db       0, 45, 63      ;
  322.                 db       0, 31, 63      ;
  323.                 db       0,  0, 63      ;               [blue]
  324.                 db      30,  0, 63      ;
  325.                 db      45,  0, 63      ;
  326.                 db      63,  0, 63      ;               [violet]
  327.                 db      63,  0, 47      ;color #15
  328. maxcolor        db      15              ;highest defined color number
  329. index           dw      0               ;index to last line in moire pattern
  330. ; current line endpoint data
  331. ; data for each coordinate is grouped so loop at [revdir] works w/offsets
  332. xv1             dw      ?               ;x1 endpoint velocity
  333. x1              dw      ?               ;endpoint of current line
  334. x1rev           db      MaxRev          ;times endpoint direction has reversed
  335. xv2             dw      ?               ;x2 endpoint velocity
  336. x2              dw      ?               ;endpoint of current line
  337. x2rev           db      MaxRev          ;times endpoint direction has reversed
  338. yv1             dw      ?               ;y1 endpoint velocity
  339. y1              dw      ?               ;endpoint of current line
  340. y1rev           db      MaxRev          ;times endpoint direction has reversed
  341. yv2             dw      ?               ;y2 endpoint velocity
  342. y2              dw      ?               ;endpoint of current line
  343. y2rev           db      MaxRev          ;times endpoint direction has reversed
  344. switchdir       dw      0               ;# lines to draw before changing to new random velocities
  345. linesx1         dw      MaxLines dup (?)        ;arrays holding endpoints of last MaxLines lines
  346. linesy1         dw      MaxLines dup (?)
  347. linesx2         dw      MaxLines dup (?)
  348. linesy2         dw      MaxLines dup (?)
  349. old08h          dw      ?               ;hold addresses of original interrupts
  350.                 dw      ?
  351. old09h          dw      ?
  352.                 dw      ?
  353. old10h          dw      ?
  354.                 dw      ?
  355. old13h          dw      ?
  356.                 dw      ?
  357. ;old14h          dw      ?
  358.                  dw      ?
  359. old17h          dw      ?
  360.                 dw      ?
  361. int10hOK        db      0               ;0 if we should reset [counter] on calls to int 10h -- while our program is running, this is 0ffh (-1)
  362. sax             dw      ?               ;saves ax
  363. sbx             dw      ?               ;saves bx
  364. scx             dw      ?               ;saves cx
  365. sdx             dw      ?               ;saves dx
  366. sdi             dw      ?               ;saves di
  367. ssi             dw      ?               ;saves si
  368. sbp             dw      ?               ;saves bp
  369. ses             dw      ?               ;saves es
  370. sds             dw      ?               ;saves ds
  371. sip             dw      ?               ;saves ip
  372. scs             dw      ?               ;saves cs
  373. sfl             dw      ?               ;saves flags
  374. sax2            dw      ?               ;saves ax in our08h
  375. sbx2            dw      ?               ;saves bx in out08h
  376. scx2            dw      ?               ;saves cx in our08h
  377. sdx2            dw      ?               ;saves dx in our08h
  378. sds2            dw      ?               ;saves ds in out08h
  379.  
  380.  
  381.  
  382. reset   proc    near                    ;resets countdown, restores screen if in "gfx cop-out" mode
  383.         push    cs:[wait]
  384.         pop     cs:[counter]
  385.         cmp     cs:[gfxmode],0
  386.         je      @@done
  387.         mov     cs:[gfxmode],0
  388.         xor     al,al                   ;restore screen if gfx cop-out mode was active
  389.         call    refresh
  390. @@done:
  391.         ret
  392. reset   endp
  393.  
  394.  
  395.  
  396. our08h  proc    near                    ;our int 08h handler
  397.         cmp     cs:[gonow],0            ;gonow > 0 if Ctrl-Alt-Shift was pressed
  398.         jz      @@deccnt
  399.         dec     cs:[gonow]              ;subtract 1 from gonow if it is > 0
  400.         jg      @@deccnt
  401.         mov     cs:[counter],1          ;if gonow=0 set counter=1 to trigger fireworks
  402. @@deccnt:
  403.         dec     cs:[counter]            ;decrement counter
  404.         jz      @@moire                 ;if counter = 0 draw moire pattern
  405.         jg      @@checkMS
  406.         inc     cs:[counter]            ;if counter was 0 set it 0 again
  407. @@checkMS:
  408.         cmp     cs:[mouse],0
  409.         je      @@chain
  410.         mov     cs:[sds2],ds            ;save ds
  411.         push    cs
  412.         pop     ds                      ;set up addressability
  413.         mov     [sax2],ax               ;save ax
  414.         mov     [sbx2],bx               ;save bx
  415.         mov     [scx2],cx               ;save cx
  416.         mov     [sdx2],dx               ;save dx
  417.         mov     ax,3
  418.         xor     bx,bx                   ;in case no mouse driver, zero all regs that would hold return values
  419.         xor     cx,cx
  420.         xor     dx,dx
  421.         int     33h
  422.         cmp     bx,0                    ;is mouse button pressed
  423.         jne     @@reset
  424.         cmp     cx,[oldmx]
  425.         jne     @@reset
  426.         cmp     dx,[oldmy]
  427.         je      @@doneMS
  428. @@reset:
  429.         mov     [oldmx],cx
  430.         mov     [oldmy],dx
  431.         call    reset                   ;reset countdown
  432. @@doneMS:
  433.         mov     dx,[sdx2]
  434.         mov     cx,[scx2]
  435.         mov     bx,[sbx2]
  436.         mov     ax,[sax2]
  437.         mov     ds,[sds2]
  438. @@chain:
  439.         jmp     DWord Ptr cs:[old08h]   ;chain to old int 08h handler
  440. @@moire:
  441.         mov     cs:[sds],ds             ;save ds first, so we can
  442.         push    cs                      ;  point ds to us to crunch code by
  443.         pop     ds                      ;  avoiding segment overrides
  444.         mov     [sax],ax                ;save ax
  445.         mov     [sbx],bx                ;save bx
  446.         mov     [scx],cx                ;save cx
  447.         mov     [sdx],dx                ;save dx
  448.         mov     [sdi],di                ;save di
  449.         mov     [ssi],si                ;save si
  450.         mov     [sbp],bp                ;save bp
  451.         mov     [ses],es                ;save es
  452.         pop     [sip]                   ;save ip
  453.         pop     [scs]                   ;save cs
  454.         pop     [sfl]                   ;save flags
  455.         push    [sfl]                   ;push flags back on stack
  456.         push    cs                      ;push new cs on stack
  457.         mov     cx,offset runthis       ;return to here
  458.         push    cx                      ;save offset of runthis
  459.         jmp     @@chain                 ;return to do int 8
  460. our08h  endp
  461.  
  462.  
  463.  
  464. our09h  proc    near                    ;process keyboard interrupt
  465.         push    ax                      ;save ax
  466.         push    es                      ;save ds
  467.         mov     es,cs:[keybuff]         ;set es = 0
  468.         mov     al,byte ptr es:[417h]   ;get keyboard status byte
  469.         pop     es
  470.         and     al,0fh                  ;mask off top 4 bits
  471.         cmp     al,12                   ;if Ctrl-Alt is pressed
  472.         jg      @@signal                ;if Ctrl-Alt-Shift is pressed
  473.         jnz     @@chain
  474.         in      al,60h                  ;get extended key code
  475.         cmp     al,18                   ;is it Ctrl-Alt-E
  476.         jnz     @@enable
  477.         mov     cs:[onoff],0            ;turn off screen saver
  478. @@enable:
  479.         cmp     al,48                   ;is key Ctrl-Alt-B
  480.         jnz     @@chain
  481.         mov     cs:[onoff],1            ;turn on screen saver
  482.         jmp     @@chain
  483. @@signal:
  484.         mov     cs:[gonow],6            ;delay half a second then invoke screen saver
  485.         mov     cs:[timeout],0          ;say we're popping up because of user request (ctrl-alt-shift)
  486. @@chain:
  487.         call    reset                   ;reset countdown
  488.         pop     ax                      ;restore ax
  489.         jmp     DWord Ptr cs:[old09h]   ;chain to old int 09h handler
  490. our09h  endp
  491.  
  492.  
  493.  
  494. our10h  proc    near                    ;new video interrupt
  495.         cmp     ax,0caffh               ;CA are my initials - check if we're installed
  496.         jne     @@norm10h
  497.         mov     bx,cs                   ;return our PSP
  498.         mov     ax,0faceh               ;return code
  499.         iret
  500. @@norm10h:
  501.         cmp     cs:[int10hOK],0         ;is it us requesting an interrupt
  502.         jne     @@pass                  ;if so, don't reset counter, or we'll exit!
  503.         call    reset                   ;reset countdown
  504.         @@pass:
  505.         jmp     DWord Ptr cs:[old10h]   ;chain to old int 10h handler
  506. our10h  endp
  507.  
  508.  
  509.  
  510. our13h  proc    near                    ;new disk drive interrupt
  511.         call    reset                   ;reset countdown
  512.         jmp     DWord Ptr cs:[old13h]   ;chain to old int 13h handler
  513. our13h  endp
  514.  
  515.  
  516.  
  517. ;our14h  proc    near                    ;new modem interrupt
  518. ;        call    reset                   ;reset countdown
  519. ;        jmp     DWord Ptr cs:[old14h]   ;chain to old int 14h handler
  520. ;our14h  endp
  521.  
  522.  
  523.  
  524. our17h  proc    near                    ;new printer interrupt
  525.         call    reset                   ;reset countdown
  526.         jmp     DWord Ptr cs:[old17h]   ;chain to old int 17h handler
  527. our17h  endp
  528.  
  529.  
  530.  
  531. ;------------------------------------------------------------------------------
  532. ;
  533. ;       CARD-SPECIFIC CODE
  534. ;
  535. ;       any include file used here must declare the following items so it
  536. ;       can link itself with this VGAMOIRE.ASM module:
  537. ;
  538. ;               SETCOLORS       (macro) sets the colors
  539. ;               STORE           (macro) stores the current video state
  540. ;               SETMODE         (macro) sets the graphics mode
  541. ;               RESTORE         (macro) restores the saved video state
  542. ;               Line10          (proc)  draws a line in graphics mode
  543. ;
  544. ;               MinBound        equ     [minimum endpoint velocity]
  545. ;               MaxBound        equ     [maximum endpoint velocity]
  546. ;
  547. ;               MaxX            dw      [maximum x coordinate]
  548. ;               MaxY            dw      [maximum y coordinate]
  549. ;
  550. include vga.inc
  551. ;
  552. ;------------------------------------------------------------------------------
  553.  
  554.  
  555.  
  556. getbuf  proc    near
  557.         cmp     cs:[useEMS],0
  558.         jz      @@done
  559.         mov     ah,47h                  ;save page map
  560.         mov     dx,cs:[EMShandle]
  561.         int     67h
  562.         or      ah,ah
  563.         jnz     @@error
  564.         mov     ah,44h                  ;map our logical pages to physical page frame
  565.         mov     al,cs:[useEMS]          ;al=number of pages we reserved
  566.         dec     al                      ;al=number of highest logical page
  567. @@maploop:
  568.         push    ax
  569.         xor     bh,bh
  570.         mov     bl,al                   ;map logical page to same physical page number
  571.         mov     dx,cs:[EMShandle]
  572.         int     67h
  573.         or      ah,ah
  574.         jnz     @@error3                ;@@error3 makes sure to pop ax, too
  575.         pop     ax
  576.         or      al,al
  577.         jz      @@getframe
  578.         dec     al
  579.         jmp     @@maploop
  580. @@getframe:
  581.         mov     ah,41h                  ;get page frame address
  582.         int     67h
  583.         or      ah,ah
  584.         jnz     @@error2
  585.         mov     cs:[storetext],bx
  586. @@done:
  587.         clc                             ;success
  588.         ret
  589. @@error3:
  590.         pop     ax
  591. @@error2:
  592.         call    freebuf                 ;uh, oh, better restore page map...
  593. @@error:
  594.         stc                             ;failure
  595.         ret
  596. getbuf  endp
  597.  
  598.  
  599.  
  600. freebuf proc    near
  601.         cmp     cs:[useEMS],0
  602.         jz      @@done
  603.         mov     ah,48h                  ;restore page map
  604.         mov     dx,cs:[EMShandle]
  605.         int     67h
  606.         or      ah,ah
  607. @@done:
  608.         ret
  609. freebuf endp
  610.  
  611.  
  612.  
  613. rndcnt          dw      ?               ;ceiling of random number range
  614. seed            dw      ?               ;seed for random number generator
  615. aval            equ     2743            ;for pseudorandom generator
  616. cval            equ     5923            ;for pseudorandom generator
  617. rnum            dw      rval            ;number of times the generator was used
  618. rval            equ     200             ;how high rnum can get before getting a new seed and reseting rnum
  619.  
  620. rnd     proc    near                    ;return pseudorandom number in range [0,rndcnt], uses a standard algorithm
  621.         push    cx
  622.         push    dx
  623.         inc     [rnum]
  624.         cmp     [rnum],rval             ;is it time to get a new seed
  625.         jl      @@getrnd
  626.         push    es
  627.         push    bx
  628.         xor     ax,ax
  629.         mov     es,ax
  630.         mov     bx,46ch
  631.         push    es:[bx]                 ;read timer
  632.         pop     [seed]                  ;store it to seed
  633.         mov     [rnum],ax
  634.         pop     bx
  635.         pop     es
  636. @@getrnd:
  637.         mov     ax,[seed]               ;seed = (seed*aval + cval) mod mval
  638.         mov     cx,aval
  639.         mul     cx
  640.         add     ax,cval
  641.         mov     [seed],ax
  642.         xor     dx,dx
  643.         mov     cx,[rndcnt]
  644.         inc     cx
  645.         or      cx,cx
  646.         jz      @@nomod                 ;if modulus 65536 (which is effectively mod 0 and thusly divide-by-zero because we're using word values)
  647.         div     cx
  648.         mov     ax,dx                   ;ax in [0,rndcnt]
  649. @@nomod:                                ;jump point if rndcnt=65535 to avoid divide by zero interrupt
  650.         pop     dx
  651.         pop     cx
  652.         ret
  653. rnd     endp
  654.  
  655.  
  656.  
  657. randvel proc    near                    ;pick a random endpoint velocity
  658. ;       ARGS:   none
  659. ;       RETS:   ax = velocity
  660.         mov     rndcnt,MaxBound*2       ;random number range [0,MaxBound*2]
  661. @@rv1:
  662.         call    rnd                     ;get random number in ax
  663.         sub     ax,MaxBound             ;ax in [-MaxBound,MaxBound]
  664.         cmp     ax,MinBound
  665.         jb      @@rv1
  666.         cmp     ax,-MinBound
  667.         ja      @@rv1
  668.         ret                             ;return w/ax
  669. randvel endp
  670.  
  671.  
  672.  
  673. getcoords       proc    near            ;load coordinates into regs
  674.         cmp     [curcolor],0
  675.         je      @@erase
  676.         mov     ax,[y2]
  677.         mov     bx,[x2]
  678.         mov     cx,[y1]
  679.         mov     dx,[x1]
  680.         ret
  681. @@erase:
  682.         mov     di,[index]              ;get index to last line in moire pattern
  683.         shl     di,1                    ;convert to word index
  684.         mov     ax,linesy2[di]
  685.         mov     bx,linesx2[di]
  686.         mov     cx,linesy1[di]
  687.         mov     dx,linesx1[di]
  688.         ret
  689. getcoords       endp
  690.  
  691.  
  692.  
  693. doline  proc    near                    ;draw a line from dx,cx to bx,ax
  694.         push    word ptr [curcolor]     ;pass parameters for line to Line10
  695.         push    ax
  696.         push    bx
  697.         push    cx
  698.         push    dx
  699.         call    Line10
  700.         ret
  701. doline  endp
  702.  
  703.  
  704.  
  705. alllines        proc    near            ;draw all lines, including mirroring
  706.         call    getcoords
  707.         call    doline                  ;draw normal first line
  708.         test    [mirror],1              ;mirror right/left?
  709.         jz      @@noRL
  710.         call    getcoords
  711.         neg     bx
  712.         add     bx,[MaxX]
  713.         neg     dx
  714.         add     dx,[MaxX]
  715.         call    doline
  716. @@noRL:
  717.         test    [mirror],2              ;mirror top/bottom?
  718.         jz      @@noTB
  719.         call    getcoords
  720.         neg     ax
  721.         add     ax,[MaxY]
  722.         neg     cx
  723.         add     cx,[MaxY]
  724.         call    doline
  725. @@noTB:
  726.         cmp     [mirror],3              ;mirror left/right/top/bottom?
  727.         jne     @@noBTH
  728.         call    getcoords
  729.         neg     ax
  730.         add     ax,[MaxY]
  731.         neg     cx
  732.         add     cx,[MaxY]
  733.         neg     bx
  734.         add     bx,[MaxX]
  735.         neg     dx
  736.         add     dx,[MaxX]
  737.         call    doline
  738. @@noBTH:
  739.         ret
  740. alllines        endp
  741.  
  742.  
  743.  
  744. drawmoire       proc    near            ;draw moire pattern
  745.         mov     [counter],0             ;zero the counter to avoid "false alerts"
  746.         ; reset tables holding old line coordinates
  747.         push    cs
  748.         pop     es
  749.         mov     di,offset linesx1
  750.         mov     cx,MaxLines*4           ;full table size (4 coordinates per line)
  751.         mov     ax,-1
  752.         rep     stosw                   ;set all elements in tables to -1 (word size)
  753.         ; get random directions, velocities, and coordinates to start the pattern
  754.         mov     [rndcnt],400
  755.         call    rnd
  756.         add     ax,200
  757.         mov     [switchdir],ax          ;store new # of lines to draw before randomly changing endpoint velocities
  758.         mov     di,(offset xv2 - offset xv1)*4  ;di is offset
  759. randir:
  760.         or      di,di
  761.         jz      ranex
  762.         sub     di,(offset xv2 - offset xv1)
  763.         cmp     di,(offset xv2 - offset xv1)*2  ;is it doing x or y?
  764.         jb      dox
  765.         mov     cx,[MaxY]
  766.         jmp     doxy
  767. dox:
  768.         mov     cx,[MaxX]
  769. doxy:
  770.         call    randvel                 ;get random endpoint velocity
  771.         mov     xv1[di],ax              ;store it
  772.         mov     [rndcnt],cx
  773.         call    rnd                     ;pick random endpoint coordinate
  774.         mov     x1[di],ax               ;store it
  775.         jmp     randir
  776. ranex:
  777.  
  778. di1:
  779.         cmp     [delay],0               ;if no delay factor requested
  780.         jz      de1
  781.         push    cx                      ;save cx
  782.         mov     ch,[delay]              ;set cx = 100h * delay
  783.         xor     cl,cl
  784. de0:
  785.         cmp     [counter],0             ;do this to waste time
  786.         cmp     [counter],0
  787.         loop    de0                     ;repeat cx times
  788.         pop     cx                      ;restore cs
  789. de1:
  790.         cmp     [counter],0             ;if a key was pressed counter > 0
  791.         jng     di4
  792.         jmp     ex1
  793. di4:
  794.  
  795.         ; is it time to randomly switch directions yet?
  796.         cmp     [switchdir],0
  797.         jnz     @@sdex
  798.         mov     [rndcnt],400            ;pick new random number of lines to draw before changing velocities
  799.         call    rnd
  800.         add     ax,200                  ;ax in [200,600]
  801.         mov     [switchdir],ax          ;store new limit
  802.         mov     di,(offset xv2 - offset xv1)*4  ;di is offset & counter in one
  803. @@sd1:
  804.         or      di,di
  805.         jz      @@sdex
  806.         sub     di,(offset xv2 - offset xv1)
  807.         call    randvel                 ;pick a random velocity
  808.         mov     xv1[di],ax              ;ax in [-MaxBound,-MinBound] or [MinBound,MaxBound]
  809.         jmp     @@sd1
  810. @@sdex:
  811.         dec     [switchdir]
  812.  
  813.         ; reverse directions if hit edges of screen -- loop crunches 4 essentially duplicate blocks of code into one
  814.         mov     di,(offset xv2 - offset xv1)*4  ;di is offset & counter in one
  815. revdir:
  816.         or      di,di
  817.         jz      revex
  818.         sub     di,(offset xv2 - offset xv1)
  819.         mov     ax,x1[di]
  820.         add     ax,xv1[di]
  821.         cmp     di,(offset xv2 - offset xv1)*2  ;is it checking x or y?
  822.         jb      checkx
  823.         cmp     ax,[MaxY]
  824.         jmp     checkxy
  825. checkx:
  826.         cmp     ax,[MaxX]
  827. checkxy:
  828.         jbe     revdir
  829.         cmp     x1rev[di],0             ;has xv_ reversed directions too many times?
  830.         jnz     rd1
  831.         mov     [rndcnt],MaxRev-1       ;pick new random limit for how many times to reverse
  832.         call    rnd
  833.         inc     al
  834.         mov     x1rev[di],al            ;store new limit
  835.         call    randvel                 ;pick a random velocity
  836.         mov     bx,xv1[di]              ;grab current velocity value
  837.         mov     bl,ah
  838.         and     bx,1000000010000000b    ;compare signs (directions) of current and new values of velocities
  839.         cmp     bh,bl
  840.         je      rb20
  841.         neg     ax                      ;if different, make same
  842. rb20:
  843.         mov     xv1[di],ax              ;ax in [-MaxBound,-MinBound] or [MinBound,MaxBound]
  844. rd1:
  845.         dec     x1rev[di]
  846.         neg     xv1[di]                 ;reverse the direction
  847.         jmp     revdir
  848. revex:
  849.  
  850.         mov     di,[index]              ;get index into saved line positions
  851.         shl     di,1                    ;convert to word index
  852.         mov     ax,[x1]
  853.         mov     linesx1[di],ax          ;put x1 into array
  854.         mov     ax,[x2]
  855.         mov     linesx2[di],ax          ;put x2 into array
  856.         mov     ax,[y1]
  857.         mov     linesy1[di],ax          ;put y1 into array
  858.         mov     ax,[y2]
  859.         mov     linesy2[di],ax          ;put y2 into array
  860.         ; increment index - this gives us the line to erase
  861.         inc     [index]                 ;index = index+1
  862.         xor     ah,ah
  863.         mov     al,[length]
  864.         cmp     [index],ax              ;is it time to wrap around
  865.         jl      nw1
  866.         xor     ax,ax
  867.         mov     [index],ax              ;reset index to 0
  868. nw1:
  869.         ; get color
  870.         cmp     [colorwait],0           ;is it time to change color
  871.         ja      @@samecolor             ;if not, jump
  872.         mov     al,[colorspeed]
  873.         mov     [colorwait],al
  874.         mov     al,[maxcolor]
  875.         cmp     [curcolor],al
  876.         jb      @@nowrap
  877.         mov     [curcolor],0            ;wrap around
  878. @@nowrap:
  879.         inc     [curcolor]              ;get next color
  880. @@samecolor:
  881.         dec     [colorwait]             ;get closer to time to change color
  882.         mov     ax,[yv2]
  883.         add     [y2],ax                 ;add yv2 to y2
  884.         mov     ax,[xv2]
  885.         add     [x2],ax                 ;add xv2 to x2
  886.         mov     ax,[yv1]
  887.         add     [y1],ax                 ;add yv1 to y1
  888.         mov     ax,[xv1]
  889.         add     [x1],ax                 ;add xv1 to x1
  890.         call    alllines                ;draw lines, including mirroring
  891.         ; erase last line(s)
  892.         mov     di,[index]              ;get index to last line in moire pattern
  893.         shl     di,1                    ;convert to word index
  894.         cmp     linesx1[di],-1          ;is there really a line to erase yet
  895.         je      di2
  896.         push    word ptr [curcolor]     ;save current color value
  897.         mov     [curcolor],0            ;color for erasing
  898.         call    alllines                ;clear last line(s) in pattern, including mirroring
  899.         pop     ax
  900.         mov     [curcolor],al           ;restore current color
  901. di2:
  902.         jmp     di1                     ;next iteration
  903. ex1:
  904. ;        mov     dx,3ceh                 ;dx = graphics controller port address
  905. ;        xor     ax,ax                   ;restore set/reset register
  906. ;        out     dx,ax
  907. ;        inc     ax                      ;restore enable set/reset register
  908. ;        out     dx,ax
  909. ;        mov     al,3                    ;data rotate/func select register #
  910. ;        out     dx,ax
  911. ;        mov     ax,0ff08h               ;restore bit mask register
  912. ;        out     dx,ax
  913.         ret
  914. drawmoire       endp
  915.  
  916.  
  917.  
  918. moire   proc    near
  919.         ; store text video screen
  920.         cmp     [gfxcopout],0           ;if gfx cop-out mode is set to "always", then jump to the cop-out routine
  921.         jne     @@gfxcopout
  922.         mov     [textbuff],TextBufferSeg+800h   ;address of text
  923.         mov     es,[keybuff]            ;set es = 0
  924.         mov     bl,byte ptr es:[449h]   ;get byte at 449h
  925.         cmp     bl,4                    ;what video mode are we in
  926.         jl      @@go                    ;if we are in text mode, go!
  927.         cmp     bl,7                    ;are we at mode 7, possibly ega
  928.         jz      @@mono
  929. @@gfxcopout:
  930.         mov     al,1                    ;in graphics mode, so just blank the screen
  931.         call    refresh
  932.         mov     [gfxmode],1             ;set flag that we're doing our graphics mode cop-out version of a screen saver
  933.         ret                             ;return to previous program
  934. @@gofail:
  935.         jmp     @@fail                  ;jump point if something goes wrong
  936. @@mono:
  937.         mov     [textbuff],TextBufferSeg        ;set textbuff to b000h if mono
  938. @@go:
  939.         mov     al,1                    ;disable screen refresh (avoid flickering during mode change, etc)
  940.         call    refresh
  941.         call    getbuf                  ;set up EMS page map if using EMS
  942.         jc      @@gofail                ;if we can't
  943.         mov     ax,2                    ;hide pointer, in case it's showing
  944.         int     33h
  945.         push    es
  946.         mov     ax,16h                  ;save mouse state
  947.         push    [storetext]             ;get segment of save buffer
  948.         pop     es
  949.         mov     dx,[buffersize]         ;offset past stored video screen
  950.         int     33h
  951.         mov     ax,21h                  ;reset the mouse
  952.         int     33h
  953.         pop     es
  954.         mov     bl,byte ptr es:[449h]   ;save video mode
  955.         mov     [videomode],bl
  956.         STORE                           ;[macro] save current video state
  957.         call    freebuf                 ;restore EMS page map (if using EMS)
  958.         SETMODE                         ;[macro] sets the graphics video mode
  959.         push    cs                      ;set ds = cs
  960.         pop     ds
  961.         SETCOLORS                       ;[macro] set new video DAC color registers
  962.         xor     al,al                   ;reenable video refresh (the BIOS should have taken care of this when we set the graphics mode, but we do it, too, just in case)
  963.         call    refresh
  964.         call    drawmoire               ;draw moire pattern
  965.         mov     al,1                    ;disable screen refresh (avoid flickering during mode change, etc)
  966.         call    refresh
  967.         push    cs
  968.         pop     ds
  969.         xor     ah,ah                   ;reset to saved mode
  970.         mov     al,[videomode]          ;  must do this, even if we're restoring the video state afterwards, otherwise the
  971.         int     10h                     ;  mouse driver thinks we're still in gfx mode and the mouse pointer gets mangled.
  972.         mov     al,1                    ;disable screen refresh (avoid flickering during mode change, etc)
  973.         call    refresh
  974.         RESTORE                         ;[macro] restore saved video state
  975. @@done:
  976.         xor     al,al                   ;reenable video refresh
  977.         call    refresh
  978.         push    cs
  979.         pop     ds
  980.         call    reset                   ;reset the countdown
  981.         ret
  982. @@fail:
  983.         cmp     [timeout],0             ;if failed but we timed out, don't do anything
  984.         jnz     @@done
  985.         mov     ah,0eh
  986.         mov     al,7                    ;cheapie way to sound a bell
  987.         xor     bx,bx
  988.         int     10h
  989.         jmp     @@done
  990. moire   endp
  991.  
  992.  
  993.  
  994. runthis proc    near                    ;run graphics then restore to program
  995.         mov     ax,cs                   ;set ds = cs
  996.         mov     ds,ax
  997.         not     [int10hOK]              ;tell our int 10h handler we're calling it
  998.         cmp     [onoff],0               ;was VGAMoire turned off
  999.         jz      @@nope
  1000.         call    moire                   ;save screen, draw moire pattern, restore screen
  1001. @@nope:
  1002.         mov     ax,[sax]                ;restore ax
  1003.         mov     bx,[sbx]                ;restore bx
  1004.         mov     cx,[scx]                ;restore cx
  1005.         mov     dx,[sdx]                ;restore dx
  1006.         mov     di,[sdi]                ;restore di
  1007.         mov     si,[ssi]                ;restore si
  1008.         mov     bp,[sbp]                ;restore bp
  1009.         mov     es,[ses]                ;restore es
  1010.         push    [sfl]                   ;put flags on stack
  1011.         push    [scs]                   ;put cs on stack
  1012.         push    [sip]                   ;put ip on stack
  1013.         mov     ds,[sds]                ;restore ds
  1014.         not     cs:[int10hOK]           ;tell our int 10h handler to reset [counter] on int requests
  1015.         mov     cs:[timeout],1          ;reset timeout indicator to say true timeout, not ctrl-alt-shift hit
  1016.         iret                            ;return to previous program
  1017. runthis endp
  1018.  
  1019.  
  1020.  
  1021.         align   16                      ;paragraph aligned so we can store just a segment address
  1022. EndOfResident   label   byte
  1023.  
  1024.  
  1025.  
  1026. _mypsp          dw      ?
  1027.  
  1028. deinstall       proc    near
  1029. ;       This could be done by simply deallocating our PSP block and environment
  1030. ;       block (if not deallocated at installation), but this is more
  1031. ;       "well-behaved", in that if a DOS extender allocates an extra info block
  1032. ;       per program, this will also deallocate that block, because it simply
  1033. ;       deallocates anything that belongs to us.
  1034. ;       This isn't resident code, so we might as well take the extra effort.
  1035.         mov     ax,0caffh               ;are we installed yet
  1036.         int     10h
  1037.         cmp     ax,0faceh
  1038.         je      @@deinstall
  1039.         mov     ah,9                    ;if not, print error message and abort
  1040.         mov     dx,offset nomsg
  1041.         int     21h
  1042.         mov     ax,4c01h
  1043.         int     21h
  1044. @@deinstall:
  1045.         mov     cs:[_mypsp],bx          ;save the PSP of the resident copy
  1046.         mov     es,bx
  1047.         mov     bl,es:[useEMS]          ;find out if resident copy is using EMS
  1048.         mov     cs:[useEMS],bl
  1049.         mov     bx,es:[EMShandle]       ;get EMS handle resident copy is using
  1050.         mov     cs:[EMShandle],bx
  1051.         mov     ax,3508h                ;check if another program covered us
  1052.         int     21h
  1053.         mov     ax,es
  1054.         cmp     ax,cs:[_mypsp]
  1055.         jne     @@yousureb
  1056.         cmp     bx,offset our08h
  1057.         jne     @@yousureb
  1058.         mov     ax,3509h
  1059.         int     21h
  1060.         mov     ax,es
  1061.         cmp     ax,cs:[_mypsp]
  1062.         jne     @@yousureb
  1063.         cmp     bx,offset our09h
  1064.         jne     @@yousureb
  1065.         mov     ax,3510h
  1066.         int     21h
  1067.         mov     ax,es
  1068.         cmp     ax,cs:[_mypsp]
  1069.         jne     @@yousureb
  1070.         cmp     bx,offset our10h
  1071.         jne     @@yousureb
  1072.         mov     ax,3513h
  1073.         int     21h
  1074.         mov     ax,es
  1075.         cmp     ax,cs:[_mypsp]
  1076.         jne     @@yousureb
  1077.         cmp     bx,offset our13h
  1078.         jne     @@yousureb
  1079. ;        mov     ax,3514h
  1080. ;        int     21h
  1081. ;        mov     ax,es
  1082. ;        cmp     ax,cs:[_mypsp]
  1083. ;        jne     @@yousureb
  1084. ;        cmp     bx,offset our14h
  1085. ;        jne     @@yousureb
  1086.         mov     ax,3517h
  1087.         int     21h
  1088.         mov     ax,es
  1089.         cmp     ax,cs:[_mypsp]
  1090.         jne     @@yousureb
  1091.         cmp     bx,offset our17h
  1092.         jne     @@yousureb
  1093.         jmp     @@yessure
  1094.         @@yousureb:
  1095.         jmp     @@yousure
  1096.         @@yessure:
  1097.         mov     bx,cs:[_mypsp]
  1098.         mov     es,bx
  1099.         mov     dx,word ptr es:[old08h]         ; get old 8h vector
  1100.         mov     ds,word ptr es:[old08h+2]
  1101.         mov     ax,2508h                        ; restore old 8h vector
  1102.         int     21h
  1103.         mov     dx,word ptr es:[old09h]         ; get old 9h vector
  1104.         mov     ds,word ptr es:[old09h+2]
  1105.         mov     ax,2509h                        ; restore old 9h vector
  1106.         int     21h
  1107.         mov     dx,word ptr es:[old10h]         ; get old 10h vector
  1108.         mov     ds,word ptr es:[old10h+2]
  1109.         mov     ax,2510h                        ; restore old 10h vector
  1110.         int     21h
  1111.         mov     dx,word ptr es:[old13h]         ; get old 13h vector
  1112.         mov     ds,word ptr es:[old13h+2]
  1113.         mov     ax,2513h                        ; restore old 13h vector
  1114.         int     21h
  1115. ;        mov     dx,word ptr es:[old14h]         ; get old 14h vector
  1116. ;        mov     ds,word ptr es:[old14h+2]
  1117. ;        mov     ax,2514h                        ; restore old 14h vector
  1118. ;        int     21h
  1119.         mov     dx,word ptr es:[old17h]         ; get old 17h vector
  1120.         mov     ds,word ptr es:[old17h+2]
  1121.         mov     ax,2517h                        ; restore old 17h vector
  1122.         int     21h
  1123.         push    cs
  1124.         pop     ds
  1125.         mov     ah,52h
  1126.         int     21h
  1127.         mov     ax,word ptr es:[bx-2]
  1128.         mov     es,ax
  1129.         @@looptop:
  1130.         cmp     byte ptr es:[0],4dh
  1131.         jne     @@end
  1132.         mov     ax,word ptr es:[1]
  1133.         cmp     ax,word ptr cs:[_mypsp]
  1134.         jne     @@notourblock
  1135.         push    es
  1136.         mov     ax,es
  1137.         inc     ax
  1138.         mov     es,ax
  1139.         mov     ah,49h
  1140.         int     21h
  1141.         pop     es
  1142.         @@notourblock:
  1143.         mov     cx,word ptr es:[3]
  1144.         inc     cx
  1145.         mov     ax,es
  1146.         add     ax,cx
  1147.         mov     es,ax
  1148.         jmp     @@looptop
  1149.         @@end:
  1150.         cmp     cs:[useEMS],0
  1151.         jz      @@noEMS
  1152.         mov     ah,45h                  ;release resident copy's EMS block, if present
  1153.         mov     dx,cs:[EMShandle]
  1154.         int     67h                     ;if there was an error, it's out of our hands
  1155.         @@noEMS:
  1156.         mov     ah,9                    ;print deinstallation msg
  1157.         mov     dx,offset demsg
  1158.         int     21h
  1159.         mov     ax,4c00h
  1160.         int     21h
  1161.         @@yousure:
  1162.         mov     dx,offset suremsg
  1163.         call    @@str29
  1164.         @@getch:
  1165.         mov     ah,8
  1166.         int     21h
  1167.         cmp     al,'y'
  1168.         je      @@dok
  1169.         cmp     al,'Y'
  1170.         je      @@dok
  1171.         cmp     al,'n'
  1172.         je      @@dok
  1173.         cmp     al,'N'
  1174.         je      @@dok
  1175.         cmp     al,27
  1176.         je      @@dok
  1177.         jmp     @@getch
  1178.         @@dok:
  1179.         push    ax
  1180.         cmp     al,27
  1181.         je      @@nopr
  1182.         int     29h                     ;undocumented character output routine
  1183.         @@nopr:
  1184.         mov     al,13                   ;go to next line
  1185.         int     29h
  1186.         mov     al,10
  1187.         int     29h
  1188.         pop     ax
  1189.         cmp     al,'y'
  1190.         je      @@yes
  1191.         cmp     al,'Y'
  1192.         je      @@yes
  1193.         mov     dx,offset stilmsg
  1194.         call    @@str29
  1195.         pop     es
  1196.         pop     di
  1197.         mov     ax,4c01h                ;exit, return ERRORLEVEL 1
  1198.         int     21h
  1199.         @@yes:
  1200.         jmp     @@yessure
  1201.         @@str29:
  1202.         mov     di,dx
  1203.         @@sloop:                        ;output routine emulates int 21h fnc 9h
  1204.         mov     al,cs:[di]
  1205.         inc     di
  1206.         cmp     al,'$'
  1207.         je      @@sexit
  1208.         int     29h                     ;undocumented character output routine
  1209.         jmp     @@sloop
  1210.         @@sexit:
  1211.         ret
  1212. deinstall       endp
  1213.  
  1214.  
  1215.  
  1216. newopts proc    near
  1217.         push    ax
  1218.         push    bx
  1219.         push    dx
  1220.         mov     ax,0caffh               ;are we installed yet
  1221.         int     10h                     ;returns bx=resident PSP if installed, and ax=0faceh
  1222.         cmp     ax,0faceh
  1223.         je      @@setnew
  1224.         mov     ah,9                    ;if not, print error message and abort
  1225.         mov     dx,offset nomsg
  1226.         int     21h
  1227.         mov     ax,4c01h
  1228.         int     21h
  1229. @@setnew:
  1230.         mov     es,bx                   ;set up to write subsequent params to resident copy
  1231.         pop     dx
  1232.         pop     bx
  1233.         pop     ax
  1234.         ret
  1235. newopts endp
  1236.  
  1237.  
  1238.  
  1239. setminutes      proc    near
  1240.         call    finddigit               ;convert string to digit
  1241.         jc      @@done
  1242.         cmp     cl,30                   ;make sure it is less than 30 minutes
  1243.         ja      @@done
  1244.         mov     ax,444h                 ;multiply digit by 444h
  1245.         mul     cx
  1246.         mov     es:[wait],ax            ;save, this is # of int 8's performed in x mins
  1247. @@done:
  1248.         ret
  1249. setminutes      endp
  1250.  
  1251.  
  1252.  
  1253. setdelay        proc    near
  1254.         call    finddigit               ;convert string to digit
  1255.         jc      @@done
  1256.         mov     es:[delay],cl           ;save digit as a delay factor
  1257. @@done:
  1258.         ret
  1259. setdelay        endp
  1260.  
  1261.  
  1262.  
  1263. setlines        proc    near
  1264.         call    finddigit               ;get digit
  1265.         jc      @@done
  1266.         cmp     cl,MaxLines             ;was number less than MaxLines
  1267.         ja      @@done
  1268.         mov     es:[length],cl          ;save number of lines
  1269. @@done:
  1270.         ret
  1271. setlines        endp
  1272.  
  1273.  
  1274.  
  1275. setpages        proc    near
  1276.         call    finddigit               ;get value specified
  1277.         jc      @@done
  1278.         cmp     cl,8                    ;if greater than 8 ignore it
  1279.         ja      @@done
  1280.         mov     ax,1000h
  1281.         xor     ch,ch
  1282.         mul     cx                      ;number of bytes to save = 1000h * cx = ax
  1283.         mov     [buffersize],ax         ;save number of bytes to save
  1284. @@done:
  1285.         ret
  1286. setpages        endp
  1287.  
  1288.  
  1289.  
  1290. setEMS  proc    near
  1291.         mov     cs:[useEMS],1
  1292.         ret
  1293. setEMS  endp
  1294.  
  1295.  
  1296.  
  1297. setsavfon       proc    near
  1298.         call    finddigit               ;get value specified
  1299.         jc      @@done
  1300.         cmp     cl,8                    ;if greater than 8 ignore it
  1301.         ja      @@done
  1302.         mov     cs:[fontblocks],cl
  1303. @@done:
  1304.         ret
  1305. setsavfon       endp
  1306.  
  1307.  
  1308.  
  1309. setvidact       proc    near
  1310.         call    finddigit               ;get value specified
  1311.         jc      @@done
  1312.         cmp     cl,2                    ;if greater than 2 ignore it
  1313.         ja      @@done
  1314.         dec     cl
  1315.         mov     es:[int10hOK],cl        ;set video activity monitor
  1316. @@done:
  1317.         ret
  1318. setvidact       endp
  1319.  
  1320.  
  1321.  
  1322. setmouse        proc    near
  1323.         call    finddigit               ;get value specified
  1324.         jc      @@done
  1325.         cmp     cl,2                    ;if greater than 2 ignore it
  1326.         ja      @@done
  1327.         dec     cl
  1328.         mov     es:[mouse],cl           ;set mouse activity monitor
  1329. @@done:
  1330.         ret
  1331. setmouse        endp
  1332.  
  1333.  
  1334.  
  1335. setblank        proc    near
  1336.         cmp     es:[gfxinstalled],0     ;was VGAMoire installed with the [Bn] option?
  1337.         jne     @@done                  ;yep, tough luck, can't change it then
  1338.         call    finddigit               ;get value specified
  1339.         jc      @@done
  1340.         cmp     cl,2                    ;if greater than 2 ignore it
  1341.         ja      @@done
  1342.         dec     cl
  1343.         mov     es:[gfxcopout],cl       ;set blank mode (graphics "cop-out" mode)
  1344.         mov     cs:[gfxinstalled],cl    ;set [gfxinstalled] to 1 if B2 is used
  1345. @@done:
  1346.         ret
  1347. setblank        endp
  1348.  
  1349.  
  1350.  
  1351. setmirror       proc    near
  1352.         call    finddigit               ;get value specified
  1353.         jc      @@done
  1354.         cmp     cl,4                    ;if greater than 4 ignore it
  1355.         ja      @@done
  1356.         dec     cl
  1357.         mov     es:[mirror],cl          ;set mirror setting
  1358. @@done:
  1359.         ret
  1360. setmirror       endp
  1361.  
  1362.  
  1363.  
  1364. setspeed        proc    near
  1365.         call    finddigit               ;get value specified
  1366.         jc      @@done
  1367.         mov     es:[colorspeed],cl      ;store speed
  1368. @@done:
  1369.         ret
  1370. setspeed        endp
  1371.  
  1372.  
  1373.  
  1374. setcolor        proc    near
  1375.         call    finddigit               ;get value specified
  1376.         jc      @@done
  1377.         cmp     cl,numsets              ;if greater than number of color sets we know of, ignore it
  1378.         ja      @@done
  1379.         push    di                      ;save di & si
  1380.         push    si
  1381.         mov     si,offset rainbow       ;get base address of color sets
  1382.         dec     cl                      ;zero-based for indexing
  1383.         xor     ah,ah
  1384.         mov     al,cl
  1385.         mov     cl,(15*3)+1             ;calc offset from [rainbow] to color set
  1386.         mul     cl
  1387.         add     si,ax                   ;calc pointer to color set to use
  1388.         mov     cx,(15*3)+1             ;number of colors to copy + maxcolor descriptor
  1389.         mov     di,offset colorset      ; es:di -> location of colorset array (where to copy to)
  1390.         rep     movsb                   ;copy color set from list of color sets into the run-time array
  1391.         pop     si
  1392.         pop     di                      ;restore di & si
  1393. @@done:
  1394.         ret
  1395. setcolor        endp
  1396.  
  1397.  
  1398.  
  1399. seton   proc    near
  1400.         mov     es:[onoff],1
  1401.         ret
  1402. seton   endp
  1403.  
  1404.  
  1405.  
  1406. setoff  proc    near
  1407.         mov     es:[onoff],0
  1408.         ret
  1409. setoff  endp
  1410.  
  1411.  
  1412.  
  1413. getEMS  proc    near
  1414.         push    di
  1415.         push    si
  1416.         mov     ax,3567h                ;test for presense of EMS
  1417.         int     21h                     ;returns es=segment ptr
  1418.         mov     di,10                   ;es:di -> byte at offset 10 in device header
  1419.         mov     si,offset emmname
  1420.         mov     cx,8
  1421.         cld
  1422.         repz    cmpsb                   ;compare strings
  1423.         jz      @@EMSthere
  1424.         mov     ah,9                    ;print message saying no EMS m.m.
  1425.         mov     dx,offset noEMS
  1426.         int     21h
  1427.         jmp     @@error
  1428. @@EMSthere:
  1429.         mov     ah,46h                  ;get version, if lower than 3.0, can't use (actually, it might work, but since i'm not sure...)
  1430.         int     67h
  1431.         cmp     al,30h
  1432.         jae     @@EMS30
  1433.         mov     ah,9                    ;print message saying we need at least EMS 3.0
  1434.         mov     dx,offset EMS30
  1435.         int     21h
  1436.         jmp     @@error
  1437. @@EMS30:
  1438.         mov     ah,43h                  ;allocate an EMS handle to use
  1439.         mov     bx,1
  1440.         cmp     cs:[buffersize],3000h   ;three vid pages or less, just one EMS page
  1441.         jbe     @@getpages
  1442.         inc     bx
  1443.         cmp     cs:[buffersize],7000h   ;seven or less, two EMS pages
  1444.         jbe     @@getpages
  1445.         inc     bx                      ;eight vid pages needs three EMS pages
  1446. @@getpages:
  1447.         mov     cs:[useEMS],bl          ;store number of pages we're allocating for video text save area
  1448.         cmp     cs:[fontblocks],0       ;should we save character RAM also
  1449.         jz      @@nochr
  1450.         xor     dh,dh
  1451.         mov     dl,cs:[fontblocks]      ;how many font blocks do we need to save
  1452.         inc     dl                      ;round up and
  1453.         shr     dl,1                    ;  convert to EMS pages
  1454.         add     bx,dx                   ;add in pages for font RAM
  1455. @@nochr:
  1456.         int     67h
  1457.         or      ah,ah
  1458.         jz      @@gotEMS
  1459.         mov     ah,9                    ;error allocating EMS, so just use conventional
  1460.         mov     dx,offset EMSerr
  1461.         int     21h
  1462.         jmp     @@error
  1463. @@gotEMS:
  1464.         mov     cs:[EMShandle],dx
  1465.         mov     ah,46h                  ;get version, if 4.0 or higher, we're going to name our block
  1466.         int     67h
  1467.         cmp     al,40h
  1468.         jb      @@done
  1469.         mov     ax,5301h                ;give our handle a name
  1470.         mov     dx,cs:[EMShandle]
  1471.         mov     si,offset EMSname
  1472.         int     67h
  1473. @@done:
  1474.         pop     si
  1475.         pop     di
  1476.         ret
  1477. @@error:
  1478.         mov     ah,9                    ;say we'll use conventional memory instead
  1479.         mov     dx,offset cnvmsg
  1480.         int     21h
  1481.         mov     cs:[useEMS],0
  1482.         mov     cs:[fontblocks],0       ;can't save fonts anymore!!
  1483.         jmp     @@done
  1484. emmname db      'EMMXXXX0'
  1485. EMSname db      'VGAMoire'
  1486. noEMS   db      'EMS memory manager not found.',13,10,'$'
  1487. EMS30   db      'VGAMoire requires EMS 3.0 or higher.',13,10,'$'
  1488. EMSerr  db      'Error allocating EMS memory.',13,10,'$'
  1489. cnvmsg  db      'Using conventional memory instead.',13,10,'$'
  1490. getEMS  endp
  1491.  
  1492.  
  1493.  
  1494. reznew          db      0               ;flag:  are we setting new params for resident copy
  1495.  
  1496. setup   proc    near                    ;main procedure for setting up program
  1497.         mov     ah,9                    ;print id string
  1498.         mov     dx,offset msg
  1499.         int     21h
  1500.         ; process the command line
  1501.         mov     di,80h                  ;set si and di to command tail
  1502.         mov     si,81h
  1503. @@nextchr:
  1504.         lodsb                           ;get next character
  1505.         cmp     al,' '                  ;is it a whitespace, space or tab or enter
  1506.         jz      @@nextchr
  1507.         cmp     al,9
  1508.         jz      @@nextchr
  1509.         cmp     al,0dh                  ;if enter quit processing
  1510.         jz      @@endln
  1511.         dec     si                      ;adjust si
  1512.         xor     al,al                   ;mark end of string with 0
  1513.         stosb
  1514. @@getchr:
  1515.         lodsb                           ;get character
  1516.         cmp     al,' '                  ;is it a whitespace
  1517.         jz      @@nextchr
  1518.         cmp     al,9
  1519.         jz      @@nextchr
  1520.         cmp     al,0dh
  1521.         jz      @@endln
  1522.         cmp     al,'a'                  ;is the character a small letter
  1523.         jl      @@storchr
  1524.         cmp     al,'z'
  1525.         jg      @@storchr
  1526.         and     al,223                  ;if so capitalize it
  1527.         cmp     al,'N'                  ;send new params?
  1528.         jne     @@storchr
  1529.         mov     [reznew],1
  1530. @@storchr:
  1531.         stosb                           ;store character again
  1532.         jmp     @@getchr
  1533. @@endln:
  1534.         xor     ax,ax                   ;put double zero in tail to mark end of buffer
  1535.         stosw
  1536.         cmp     [reznew],1              ;should we set options for resident copy?
  1537.         jne     @@parse
  1538.         call    newopts
  1539. @@parse:
  1540.         ; parse the command line and act on parameters
  1541.         mov     si,80h                  ;start reading here
  1542.         cmp     word ptr [si+1],'?'     ;was '?' input
  1543.         jnz     @@findnull
  1544.         mov     ah,9                    ;then print message describing switches
  1545.         mov     dx,offset usage
  1546.         int     21h
  1547.         mov     ax,4c00h                ;and quit with error level 0
  1548.         int     21h
  1549. @@findnull:
  1550.         lodsb                           ;read character until we get a 0
  1551.         or      al,al
  1552.         jnz     @@findnull
  1553.         cmp     byte ptr [si],al        ;is next character a 0, are we finished ?
  1554.         jnz     @@continue
  1555.         jmp     @@donepar
  1556. @@continue:
  1557.         lodsb                           ;get character
  1558.         xor     bp,bp                   ;compare to valid options
  1559. @@nextone:
  1560.         mov     ah,cs:[bp + offset options]
  1561.         or      ah,ah
  1562.         jz      @@findnull
  1563.         cmp     ah,al
  1564.         je      @@gotone
  1565.         inc     bp
  1566.         jmp     @@nextone
  1567. @@gotone:
  1568.         shl     bp,1                    ;convert to word index
  1569.         call    word ptr cs:[bp + offset optaddr]
  1570.         jmp     @@findnull
  1571. @@donepar:
  1572.         cmp     [useEMS],0
  1573.         jnz     @@possiblefont
  1574.         mov     [fontblocks],0
  1575. @@possiblefont:
  1576. ;        push    cs
  1577. ;        pop     es
  1578.         cmp     [reznew],0
  1579.         jz      @@start
  1580.         ; -- possible enhancement: display current settings before exitting
  1581.         mov     ah,9                    ;display msg that params have been updated
  1582.         mov     dx,offset newmsg
  1583.         int     21h
  1584.         mov     ax,4c00h
  1585.         int     21h
  1586. @@start:
  1587.         ; start the moire pattern without going resident
  1588.         call    noresident
  1589.         cmp     [useEMS],0
  1590.         jz      @@noEMS
  1591.         call    getEMS
  1592. @@noEMS:
  1593.         mov     ax,0caffh               ;are we installed yet
  1594.         int     10h
  1595.         cmp     ax,0faceh
  1596.         jne     @@storevec
  1597.         mov     ah,9                    ;if so, print error message and abort
  1598.         mov     dx,offset ainmsg
  1599.         int     21h
  1600.         mov     ax,4c01h
  1601.         int     21h
  1602. @@storevec:
  1603.         ; store interrupt vectors
  1604.         mov     ax,3508h                ;save int 08h vector
  1605.         int     21h
  1606.         mov     word ptr [old08h],bx
  1607.         mov     word ptr [old08h+2],es
  1608.         mov     ah,25h                  ;install our int 08h
  1609.         mov     dx,offset our08h
  1610.         int     21h
  1611.         mov     ax,3509h                ;save int 09h vector
  1612.         int     21h
  1613.         mov     word ptr [old09h],bx
  1614.         mov     word ptr [old09h+2],es
  1615.         mov     ah,25h                  ;install our int 09h
  1616.         mov     dx,offset our09h
  1617.         int     21h
  1618.         mov     ax,3510h                ;save int 10h vector
  1619.         int     21h
  1620.         mov     word ptr [old10h],bx
  1621.         mov     word ptr [old10h+2],es
  1622.         mov     ah,25h                  ;install our int 10h
  1623.         mov     dx,offset our10h
  1624.         int     21h
  1625.         mov     ax,3513h                ;save int 13h vector
  1626.         int     21h
  1627.         mov     word ptr [old13h],bx
  1628.         mov     word ptr [old13h+2],es
  1629.         mov     ah,25h                  ;install our int 13h
  1630.         mov     dx,offset our13h
  1631.         int     21h
  1632. ;        mov     ax,3514h                ;save int 14h vector
  1633. ;        int     21h
  1634. ;        mov     word ptr [old14h],bx
  1635. ;        mov     word ptr [old14h+2],es
  1636. ;        mov     ah,25h                  ;install our int 14h
  1637. ;        mov     dx,offset our14h
  1638. ;        int     21h
  1639.         mov     ax,3517h                ;save int 17h vector
  1640.         int     21h
  1641.         mov     word ptr [old17h],bx
  1642.         mov     word ptr [old17h+2],es
  1643.         mov     ah,25h                  ;install our int 17h
  1644.         mov     dx,offset our17h
  1645.         int     21h
  1646. if __DeallocateEnvironment
  1647.         mov     ax,word ptr ds:[2ch]    ; deallocate our environment block
  1648.         mov     es,ax
  1649.         mov     ah,49h
  1650.         int     21h
  1651. endif
  1652.         mov     ah,9                    ;print install message
  1653.         mov     dx,offset inmsg
  1654.         int     21h
  1655.         ; set up and install VGAMoire
  1656.         push    [wait]                  ;set counter = wait
  1657.         pop     [counter]
  1658.         xor     dx,dx
  1659.         cmp     [useEMS],0
  1660.         jnz     @@yesEMS
  1661.         mov     [storetext],cs          ;make pointer to video save area
  1662.         mov     ax,offset EndOfResident
  1663.         mov     cl,4
  1664.         shr     ax,cl
  1665.         add     [storetext],ax          ;got new address for conventional memory video save buffer
  1666.         xor     bx,bx                   ;set bx=0 in case no mouse driver!!!
  1667.         mov     ax,15h                  ;find size of mouse state buffer
  1668.         int     33h
  1669.         mov     [mousesize],bx          ;store size of mouse buffer
  1670.         push    bx
  1671. ;+*VGA
  1672.         mov     ax,1c00h                ;get size of video state save buffer
  1673.         mov     cx,7
  1674.         int     10h
  1675.         mov     cl,6                    ;multiple by 64
  1676.         shl     bx,cl
  1677.         mov     dx,bx
  1678. ;-*VGA
  1679.         pop     bx
  1680.         cmp     [gfxcopout],0           ;if gfx cop-out mode is in effect, don't reserve any memory
  1681.         jne     @@yesEMS
  1682.         add     dx,[buffersize]         ;plus space to reserve for text buffer
  1683.         add     dx,bx                   ;and for mouse state buffer
  1684. @@yesEMS:
  1685.         add     dx,offset EndOfResident ;actual program code to reserve
  1686.         inc     dx                      ;for int 27h, dx = (offset last_byte) + 1
  1687.         int     27h
  1688. setup endp
  1689.  
  1690.  
  1691.  
  1692. finddigit       proc    near            ;convert string to digit
  1693.         xor     ax,ax                   ;set ax = 0 = cx, bx = 10
  1694.         mov     bx,10
  1695.         mov     cx,ax
  1696. @@nextdigit:
  1697.         lodsb                           ;get next character
  1698.         or      al,al                   ;are we at end
  1699.         jz      @@done
  1700.         cmp     al,'9'                  ;was character bigger than 9
  1701.         jg      @@fail
  1702.         sub     al,'0'                  ;or less than zero
  1703.         jl      @@fail
  1704.         xchg    ax,cx                   ;cx = cx * 10 + ax
  1705.         mul     bx
  1706.         add     cx,ax
  1707.         or      ch,ch                   ;is cx > 255
  1708.         jz      @@nextdigit
  1709. @@fail:
  1710.         dec     si                      ;return with failure
  1711.         stc
  1712.         ret
  1713. @@done:
  1714.         or      cx,cx                   ;is cx = 0 then return failure
  1715.         jz      @@fail
  1716.         dec     si                      ;return with success
  1717.         clc
  1718.         ret
  1719. finddigit       endp
  1720.  
  1721.  
  1722.  
  1723. ;memprob         db      'Memory allocation error.',13,10,'$'
  1724.  
  1725. noresident      proc    near            ;run graphics w/o staying resident
  1726.         cmp     [wait],0                ;was wait time specified
  1727.         jz      nr1
  1728.         ret                             ;if so, return and install
  1729. nr1:
  1730. ;        mov     ah,4ah                  ;free unneeded memory
  1731. ;        mov     bx,sp
  1732. ;        mov     cl,4
  1733. ;        shr     bx,cl
  1734. ;        inc     bx                      ;extra paragraph
  1735. ;        push    cs
  1736. ;        pop     es
  1737. ;        int     21h
  1738. ;        jnc     @@nonres_ok
  1739. ;        mov     ah,9
  1740. ;        mov     dx,offset memprob
  1741. ;        int     21h
  1742. ;        mov     ax,4c01h
  1743. ;        int     21h
  1744. ;@@nonres_ok:
  1745.         mov     [buffersize],8000h      ;save all video text RAM
  1746.         cmp     [useEMS],0
  1747.         jz      @@noEMS1
  1748.         call    getEMS
  1749. @@noEMS1:
  1750.         mov     [wait],444h             ;give wait a value so we don't loop endlessly!
  1751.         mov     [counter],444h
  1752.         cmp     [useEMS],0
  1753.         jnz     @@yesEMS
  1754.         mov     [storetext],cs          ;make our video save buffer be after all important code
  1755.         mov     ax,offset EndOfNonresident
  1756.         mov     cl,4
  1757.         shr     ax,cl
  1758.         add     [storetext],ax          ;got new address for conventional memory video save buffer
  1759.         @@yesEMS:
  1760.         mov     ax,3509h                ;save int 09h vector
  1761.         int     21h
  1762.         mov     word ptr [old09h],bx
  1763.         mov     word ptr [old09h+2],es
  1764.         mov     ax,2509h                ;install our int 09h
  1765.         mov     dx,offset our09h
  1766.         int     21h
  1767.         mov     ax,3508h                ;save int 08h vector
  1768.         int     21h
  1769.         mov     word ptr [old08h],bx
  1770.         mov     word ptr [old08h+2],es
  1771.         mov     ax,2508h                ;install our int 08h
  1772.         mov     dx,offset our08h
  1773.         int     21h
  1774.         push    es                      ;timer-based pause loop
  1775.         mov     es,[keybuff]
  1776.         mov     bx,46ch
  1777.         mov     cx,es:[bx]              ;read timer
  1778. @@tryagain:
  1779.         mov     dx,es:[bx]              ;read timer
  1780.         sub     dx,cx                   ;find difference
  1781.         test    dx,8000h                ;negative?
  1782.         jz      @@pos
  1783.         neg     dx                      ;take absolute value
  1784. @@pos:
  1785.         cmp     dx,3                    ;wait a smidgen
  1786.         jb      @@tryagain
  1787.         pop     es
  1788.         mov     [timeout],1
  1789.         mov     [counter],1
  1790.         @@untildone:
  1791.         cmp     [counter],10            ;wait until counter gets reset (ie, mouse or keyboard activity)
  1792.         jb      @@untildone
  1793.         mov     ax,2508h                ;restore old int 08h handler
  1794.         mov     dx,word ptr [old08h]    ;  (don't need to use a CS: override yet)
  1795.         mov     ds,word ptr [old08h+2]
  1796.         int     21h
  1797.         mov     ax,2509h                ;restore old int 09h handler
  1798.         mov     dx,word ptr cs:[old09h] ;  (from here on we need CS: overrides)
  1799.         mov     ds,word ptr cs:[old09h+2]
  1800.         int     21h
  1801.         push    cs                      ;restore DS: addressability
  1802.         pop     ds
  1803.         cmp     [useEMS],0
  1804.         jz      @@noEMS2
  1805.         mov     ah,45h                  ;release EMS block, if present
  1806.         mov     dx,[EMShandle]
  1807.         int     67h                     ;if there was an error, it's out of our hands
  1808.         @@noEMS2:
  1809.         mov     ax,4c00h                ;exit, errorlevel 0
  1810.         int     21h
  1811. noresident endp
  1812.  
  1813.  
  1814.  
  1815.         align   16                      ;paragraph aligned so we can just store a segment address
  1816. EndOfNonresident        label   byte
  1817.  
  1818.  
  1819.  
  1820. options         db      'BCDEFLMPRSUVW-+',0
  1821. optaddr         label   word
  1822.                 dw      setblank
  1823.                 dw      setcolor
  1824.                 dw      setdelay
  1825.                 dw      setEMS
  1826.                 dw      setsavfon
  1827.                 dw      setlines
  1828.                 dw      setmouse
  1829.                 dw      setpages
  1830.                 dw      setmirror
  1831.                 dw      setspeed
  1832.                 dw      deinstall
  1833.                 dw      setvidact
  1834.                 dw      setminutes
  1835.                 dw      setoff
  1836.                 dw      seton
  1837.  
  1838. msg             db      13,10
  1839.                 db      'VGAMoire ',VERSION,',  by Christopher Antos,  ',DATE,',  (C)1990',13,10,'$'
  1840. inmsg           db      '++ VGAMoire now installed.',13,10,'$'
  1841. nomsg           db      '** VGAMoire has not been installed yet.',13,10,'$'
  1842. ainmsg          db      '** VGAMoire is already installed.',13,10
  1843.                 db      '   Use VGAMOIRE U to deinstall.',13,10
  1844.                 db      '   Use VGAMOIRE N to set new parameters.',13,10,'$'
  1845. demsg           db      '-- VGAMoire now deinstalled.',13,10,'$'
  1846. suremsg         db      13,10
  1847.                 db      'Another program has captured VGAMoire''s interrupt vectors.',13,10
  1848.                 db      'Deinstalling VGAMoire may cause a system crash.',13,10
  1849.                 db      'Are you sure you want to deinstall VGAMoire? $'
  1850. stilmsg         db      '** VGAMoire is still installed.',13,10,'$'
  1851. newmsg          db      '++ New parameters sent to resident VGAMoire.',13,10,'$'
  1852. usage           db      13,10
  1853.                 db      'Usage:  VGAMOIRE [Bn] [Cn] [Dn] [E] [Fn] [Ln] [Mn] [N]',13,10
  1854.                 db      '                 [Pn] [Rn] [Sn] [U] [Vn] [Wn] [-] [+]',13,10
  1855.                 db      10
  1856.                 db      'Summary of options:                      * = invalid if used with [N]',13,10
  1857.                 db      '  Bn    blank:  1-graphics, 2-always     Pn  * save <n> video pages (1-8)',13,10
  1858.                 db      '  Cn    colors:  1-rainbow, 2-fire,      Rn    mirror:  1-none, 2-H, 3-V, 4-H/V',13,10
  1859.                 db      '        3-frost, 4-pastel                Sn    color speed:  (1-255)',13,10
  1860.                 db      '  Dn    delay:  (1-255)                  U     uninstall',13,10
  1861.                 db      '  E   * use EMS                          Vn    video:  1-monitor, 2-ignore',13,10
  1862.                 db      '  Fn  * save <n> font blocks (1-8)       Wn    wait <n> minutes (1-30)',13,10
  1863.                 db      '  Ln    lines:  (1-50)                   -     turn off',13,10
  1864.                 db      '  Mn    mouse:  1-monitor, 2-ignore      +     turn on',13,10
  1865.                 db      '  N     send options to resident copy    ',13,10
  1866.                 db      10
  1867.                 db      '    Press Ctrl-Alt-Shift to pop up screen saver.  The screen saver may be',13,10
  1868.                 db      '    disabled by pressing Ctrl-Alt-E and reenabled by pressing Ctrl-Alt-B.',13,10
  1869.                 db      '    Use  VGAMOIRE - N  to turn off resident copy (or  + N  to turn back on).',13,10
  1870.                 db      '$'
  1871.  
  1872.  
  1873.  
  1874. numsets         equ     5               ;number of color sets defined
  1875.  
  1876. ; R,G,B values for video DAC color registers
  1877.  
  1878. rainbow         db      63,  0,  0      ;color #1       [red]
  1879.                 db      63, 30,  0      ;
  1880.                 db      63, 45,  0      ;
  1881.                 db      63, 63,  0      ;               [yellow]
  1882.                 db      42, 63,  0      ;
  1883.                 db       0, 63,  0      ;               [green]
  1884.                 db       0, 63, 42      ;
  1885.                 db       0, 63, 63      ;               [cyan]
  1886.                 db       0, 45, 63      ;
  1887.                 db       0, 31, 63      ;
  1888.                 db       0,  0, 63      ;               [blue]
  1889.                 db      30,  0, 63      ;
  1890.                 db      45,  0, 63      ;
  1891.                 db      63,  0, 63      ;               [violet]
  1892.                 db      63,  0, 47      ;color #15
  1893.                 db      15
  1894.  
  1895. fire            db      63,  0,  0      ;color #1       [red]
  1896.                 db      63,  7,  0
  1897.                 db      63, 13,  0
  1898.                 db      63, 22,  0
  1899.                 db      63, 27,  0
  1900.                 db      63, 32,  0
  1901.                 db      63, 36,  0
  1902.                 db      63, 42,  0
  1903.                 db      63, 48,  0
  1904.                 db      63, 52,  0
  1905.                 db      63, 58,  0
  1906.                 db      63, 63,  0      ;color #13      [yellow]
  1907.                 db      63, 49,  0
  1908.                 db      63, 40,  0
  1909.                 db      63, 30,  0
  1910.                 db      15
  1911.  
  1912. frost           db      63, 21, 63      ;color #1       [purple]
  1913.                 db      52, 21, 63
  1914.                 db      42, 21, 63
  1915.                 db      31, 21, 63
  1916.                 db      21, 21, 63      ;color #5       [blue]
  1917.                 db      21, 29, 63
  1918.                 db      21, 38, 63
  1919.                 db      21, 46, 63
  1920.                 db      21, 54, 63
  1921.                 db      21, 63, 63      ;color #10      [cyan]
  1922.                 db      35, 63, 63
  1923.                 db      49, 63, 63
  1924.                 db      63, 63, 63      ;color #13      [white]
  1925.                 db      63, 49, 63
  1926.                 db      63, 35, 63
  1927.                 db      15
  1928.  
  1929. pastel          db      63, 47, 47      ;color #1       [red]
  1930.                 db      63, 50, 47      ;
  1931.                 db      63, 54, 47      ;
  1932.                 db      63, 58, 47      ;
  1933.                 db      63, 63, 47      ;               [orange]
  1934.                 db      59, 63, 47      ;
  1935.                 db      55, 63, 47      ;               [yellow]
  1936.                 db      47, 63, 49      ;
  1937.                 db      47, 63, 58      ;               [green]
  1938.                 db      47, 62, 63      ;
  1939.                 db      47, 57, 63      ;               [cyan]
  1940.                 db      47, 50, 63      ;
  1941.                 db      51, 47, 63      ;
  1942.                 db      58, 47, 63      ;               [violet]
  1943.                 db      63, 47, 57      ;color #15
  1944.                 db      15
  1945.  
  1946. test            db      63, 63, 63      ;
  1947.                 db      33, 33, 33      ;
  1948.                 db      63, 63, 63      ;
  1949.                 db      33, 33, 33      ;
  1950.                 db      63, 63, 63      ;
  1951.                 db      33, 33, 33      ;
  1952.                 db      63, 63, 63      ;
  1953.                 db      63, 63, 63      ;
  1954.                 db      33, 33, 33      ;
  1955.                 db      63, 63, 63      ;
  1956.                 db      33, 33, 33      ;
  1957.                 db      63, 63, 63      ;
  1958.                 db       0,  0,  0      ;
  1959.                 db       0,  0,  0      ;
  1960.                 db       0,  0,  0      ;
  1961.                 db      12
  1962.  
  1963. cseg    ends
  1964.  
  1965.  
  1966.  
  1967. public  EMS30
  1968. public  EMSerr
  1969. public  EMShandle
  1970. public  EMSname
  1971. public  EndOfNonresident
  1972. public  EndOfResident
  1973. public  MaxLines
  1974. public  MaxRev
  1975. public  _mypsp
  1976. public  ainmsg
  1977. public  alllines
  1978. public  aval
  1979. public  blackcolor
  1980. public  buffersize
  1981. public  checkx
  1982. public  checkxy
  1983. public  cnvmsg
  1984. public  colorset
  1985. public  colorspeed
  1986. public  colorwait
  1987. public  counter
  1988. public  curcolor
  1989. public  cval
  1990. public  de0
  1991. public  de1
  1992. public  deinstall
  1993. public  delay
  1994. public  demsg
  1995. public  di1
  1996. public  di2
  1997. public  di4
  1998. public  doline
  1999. public  dox
  2000. public  doxy
  2001. public  drawmoire
  2002. public  emmname
  2003. public  ex1
  2004. public  finddigit
  2005. public  fire
  2006. public  fontblocks
  2007. public  freebuf
  2008. public  frost
  2009. public  getEMS
  2010. public  getbuf
  2011. public  getcoords
  2012. public  gfxcopout
  2013. public  gfxinstalled
  2014. public  gfxmode
  2015. public  gonow
  2016. public  index
  2017. public  inmsg
  2018. public  int10hOK
  2019. public  keybuff
  2020. public  length
  2021. public  linesx1
  2022. public  linesx2
  2023. public  linesy1
  2024. public  linesy2
  2025. public  main
  2026. public  maxcolor
  2027. public  mirror
  2028. public  moire
  2029. public  mouse
  2030. public  mousesize
  2031. public  msg
  2032. public  newmsg
  2033. public  newopts
  2034. public  noEMS
  2035. public  nomsg
  2036. public  noresident
  2037. public  nr1
  2038. public  numsets
  2039. public  nw1
  2040. public  old08h
  2041. public  old09h
  2042. public  old10h
  2043. public  old13h
  2044. public  old17h
  2045. public  oldmx
  2046. public  oldmy
  2047. public  onoff
  2048. public  optaddr
  2049. public  options
  2050. public  our08h
  2051. public  our09h
  2052. public  our10h
  2053. public  our13h
  2054. public  our17h
  2055. public  pastel
  2056. public  rainbow
  2057. public  randir
  2058. public  randvel
  2059. public  ranex
  2060. public  rb20
  2061. public  rd1
  2062. public  reset
  2063. public  revdir
  2064. public  revex
  2065. public  reznew
  2066. public  rnd
  2067. public  rndcnt
  2068. public  rnum
  2069. public  runthis
  2070. public  rval
  2071. public  sax
  2072. public  sax2
  2073. public  sbp
  2074. public  sbx
  2075. public  sbx2
  2076. public  scs
  2077. public  scx
  2078. public  scx2
  2079. public  sdi
  2080. public  sds
  2081. public  sds2
  2082. public  sdx
  2083. public  sdx2
  2084. public  seed
  2085. public  ses
  2086. public  setEMS
  2087. public  setblank
  2088. public  setcolor
  2089. public  setdelay
  2090. public  setlines
  2091. public  setminutes
  2092. public  setmirror
  2093. public  setmouse
  2094. public  setoff
  2095. public  seton
  2096. public  setpages
  2097. public  setsavfon
  2098. public  setspeed
  2099. public  setup
  2100. public  setvidact
  2101. public  sfl
  2102. public  sip
  2103. public  ssi
  2104. public  stilmsg
  2105. public  storetext
  2106. public  suremsg
  2107. public  switchdir
  2108. public  textbuff
  2109. public  timeout
  2110. public  usage
  2111. public  useEMS
  2112. public  videomode
  2113. public  wait
  2114. public  x1
  2115. public  x1rev
  2116. public  x2
  2117. public  x2rev
  2118. public  xv1
  2119. public  xv2
  2120. public  y1
  2121. public  y1rev
  2122. public  y2
  2123. public  y2rev
  2124. public  yv1
  2125. public  yv2
  2126.  
  2127.  
  2128.  
  2129.         end     main
  2130.  
  2131. ;______ EOF ___________________________________________________________________
  2132.